import json
import os
import socket
import sqlite3

import requests

from makelink import create_link


class Torrent:
    def __init__(self, hash_code, is_downloading):
        self.hash_code = hash_code
        self.is_downloading = is_downloading


def get_local_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip


# 获取qbittorrent的webapi的地址
url = os.getenv('HL_QBIT_URL', 'http://%s:8080' % get_local_ip())
if url[-1] != '/':
    url += '/api/v2/torrents/'
else:
    url += 'api/v2/torrents/'
# 数据库名
db_name = 'torrents.db'
table_name = 'status'
# 建表sql语句
create_status_table_cmd = '''CREATE TABLE IF NOT EXISTS status
    (id INTEGER PRIMARY KEY NOT NULL,
     hash CHAR(50),
     is_completed INTEGER)
    '''


def create_table():
    conn = sqlite3.connect(db_name)
    c = conn.cursor()
    c.execute(create_status_table_cmd)
    conn.commit()
    conn.close()


def get_list():
    """
    通过api获取所有的种子信息

    :return: list or None for error
    """
    # 获取所有的种子信息
    request_url = url + 'info'
    print('GET: %s' % request_url)
    r = requests.get(request_url)
    if r.status_code == 200:
        lst = json.loads(r.text)
        return lst
    else:
        print("GET torrent list failed.")
        return None


def check_and_save(c, hs, is_completed):
    """
    检查该hash值的种子状态，并进行更新

    :param c: cursor
    :param hs: 哈希值
    :param is_completed: 下载状态
    :return: True-进行了更新，False-无需更新
    """
    cmd = 'SELECT is_completed FROM %s WHERE hash=?' % table_name
    c.execute(cmd, (hs,))
    row = c.fetchone()
    # 已有记录
    if row is not None:
        completed = True if row[0] == 1 else False
        if not completed and is_completed:
            # 种子的状态由下载转为完成
            cmd = 'UPDATE %s SET is_completed=1 WHERE hash=?' % table_name
            # 更新数据
            c.execute(cmd, (hs,))
            return True
    else:
        # 没有记录，直接插入
        cmd = 'INSERT INTO %s VALUES(?,?,?)' % table_name
        value = 1 if is_completed else 0
        c.execute(cmd, (None, hs, value))
        return True
    return False


def check_list(error_lst, lst=None):
    """
    检查种子列表，并更新数据库中的种子状态。对于新完成的种子，对其目录建立硬链接

    :param error_lst: 出错的种子列表，需要进一步处理
    :param lst: 全部的种子列表
    :return: None
    """
    if lst:
        con = sqlite3.connect('torrents.db')
        c = con.cursor()
        for item in lst:
            hash_code = item.get('hash', '')
            complete_time = item.get('completion_on', -1)
            if len(hash_code) > 0:
                if complete_time > 0:
                    # 已完成
                    updated = check_and_save(c, hash_code, True)
                    if updated:
                        # 种子状态转为已完成，需要建立硬链接
                        download_path = item.get('content_path', '')
                        create_link(download_path)
                else:
                    check_and_save(c, hash_code, False)
            else:
                # 没有哈希值，需要进一步处理
                error_lst.append(item)
        con.commit()
        con.close()


create_table()

if __name__ == "__main__":
    errors = []
    torrents = get_list()
    check_list(errors, torrents)
